<!--
 * @Description: 新建隧道
 * @Author: 0001100986/LiuShuai
 * @Date: 2021-07-17 09:04:06
 * @LastEditTime: 2021-11-17 11:01:25
 * @LastEditors: 0001101008/HuYuxi
-->
<template>
  <div class="tunnel-content">
    <div class="info">
      <h1 class="title">新建隧道</h1>
      <el-alert
        title="友情提示：隧道两端如果都是INTERNET链路，且都是私网地址，是无法成功建链的！建议隧道两端WAN口选择的时候，尽量使用相同运营商，获得更好的客户体验！"
        type="warning"
        show-icon
      ></el-alert>
      <el-form :model="form" class="form" :rules="rules" ref="tunnelForm" label-width="100px">
        <!-- 名称 -->
        <el-form-item label="名称" prop="userlabel" key="userlabel">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-input v-model="form.userlabel" maxlength="200" />
          </el-col>
        </el-form-item>
        <!-- 类型 -->
        <el-form-item label="隧道类型" prop="type" key="type">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.type" style="width: 100%;">
              <el-option value="EVPN_OVER_IPSEC" label="EVPN OVER IPSEC"></el-option>
              <el-option value="EVPN_OVER_IPSEC_OVER_L2TP" label="EVPN OVER IPSEC OVER L2TP"></el-option>
              <el-option value="EVPN_OVER_IPSEC_OVER_GRE" label="EVPN OVER IPSEC OVER GRE"></el-option>
              <el-option value="EVPN_OVER_IPSEC_OVER_L2TPGRE" label="EVPN OVER IPSEC OVER L2TP/GRE"></el-option>
            </el-select>
          </el-col>
        </el-form-item>
        <!-- IP类型 -->
        <el-form-item label="IP类型" prop="ipVersion" key="ipVersion">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.ipVersion" style="width: 100%;">
              <el-option value="V4" label="IPv4"></el-option>
              <el-option value="V6" label="IPv6"></el-option>
            </el-select>
          </el-col>
        </el-form-item>
        <!-- DeployDomain -->
        <!-- <el-form-item label="Domain" prop="deployDomain" key="deployDomain">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.deployDomain" style="width: 100%;">
              <el-option value="BOTH" label="BOTH"></el-option>
              <el-option value="START" label="START"></el-option>
              <el-option value="END" label="END"></el-option>
            </el-select>
          </el-col>
        </el-form-item>-->
        <!-- 源端 -->
        <el-form-item label="源" prop="start" key="start">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-cascader
              v-model="form.start"
              :props="startOptions"
              style="width: 100%;"
              @change="handleChange"
              clearable
            ></el-cascader>
          </el-col>
        </el-form-item>
        <template v-if="form.start.length === 4">
          <!-- 源端接口地址 -->
          <el-form-item label="IPSEC地址" class="ip-mask">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.startNeIpsecIp" placeholder="IP地址" />
              <label>/</label>
              <el-input v-model.number="form.startMask" placeholder="掩码" />
            </el-col>
          </el-form-item>
          <!-- AS -->
          <el-form-item label="本端AS" prop="startAs" key="startAs">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model.number="form.startAs" maxlength="10" />
            </el-col>
          </el-form-item>
          <!--  源端 WAN地址 -->
          <el-form-item v-if="form.type !== 'EVPN_OVER_IPSEC'" label="WAN地址">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.startWanIp" placeholder="IP地址" />
            </el-col>
          </el-form-item>
          <!-- 目的端 -->
          <el-form-item label="目的" prop="end" key="end">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-cascader v-model="form.end" :props="endOptions" style="width: 100%;" clearable></el-cascader>
            </el-col>
          </el-form-item>
          <!-- 目的端接口地址 -->
          <el-form-item v-if="form.end.length === 4" label="IPSEC地址" class="ip-mask">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.endNeIpsecIp" placeholder="IP地址" />
              <label>/</label>
              <el-input v-model.number="form.endMask" placeholder="掩码" />
            </el-col>
          </el-form-item>
          <!-- AS -->
          <el-form-item v-if="form.end.length === 4" label="对端AS" prop="endAs" key="endAs">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model.number="form.endAs" maxlength="10" />
            </el-col>
          </el-form-item>
          <!--  目的 WAN地址 -->
          <el-form-item v-if="form.type !== 'EVPN_OVER_IPSEC'" label="WAN地址">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.endWanIp" placeholder="IP地址" />
            </el-col>
          </el-form-item>
        </template>
        <!-- 监控 -->
        <el-form-item label="监控" prop="enableSqa" key="enableSqa">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-switch v-model="form.enableSqa" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
          </el-col>
        </el-form-item>
        <el-form-item label="丢包率" prop="lossRatio" key="lossRatio">
          <el-input-number v-model="form.lossRatio" :min="1" :max="80"></el-input-number>&nbsp;&nbsp;%
        </el-form-item>
        <el-form-item label="时延" prop="delayThreshold" key="delayThreshold">
          <el-input-number v-model="form.delayThreshold" :min="1" :max="400"></el-input-number>&nbsp;&nbsp;ms
        </el-form-item>
        <el-form-item label="抖动" prop="jitter" key="jitter">
          <el-input-number v-model="form.jitter" :min="1" :max="100"></el-input-number>&nbsp;&nbsp;ms
        </el-form-item>
        <el-form-item>
          <el-button style="width: 90px" @click="cancel">返回</el-button>
          <el-button type="primary" style="width: 90px" @click="submitForm('tunnelForm')">创建</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
export default {
  props: ['tenants'],
  created () {
    let tenants = this.tenants;
    this.startOptions = {
      lazy: true,
      lazyLoad: (node, resolve) => {
        const { level } = node;
        // 初始一级参数
        if (level === 0) {
          let nodes = tenants.map(item => {
            return {
              value: item.value,
              label: item.label,
              leaf: level >= 3
            };
          });
          resolve(nodes);
        }
        // 二级
        if (level === 1) {
          this.$http.get({
            url: '/api/sdwan/site/getSiteListByDgId/' + node.data.value
          }).then(res => {
            let { status, resultBody } = res;
            if (status === '0') {
              let sites = [];
              resultBody.map(item => {
                sites.push({
                  value: item.id,
                  label: item.sitename,
                  info: item,
                  leaf: level >= 3
                });
              });
              resolve(sites);
            }
          });
        }
        // 三级
        if (level === 2) {
          this.site = node.data.info;
          let neArry = node.data.info.nes;
          // 判断是否存在网元
          if (neArry.length === 0) {
            let nes = [];
            resolve(nes);
          } else {
            let nes = neArry.map((item) => {
              return {
                value: item.ne.id,
                label: item.ne.userlabel,
                info: item,
                wans: node.data.info.wans,
                leaf: level >= 3
              };
            });
            resolve(nes);
          }
        }
        // 四级
        if (level === 3) {
          let wans = node.data.wans;
          let info = node.data.info;
          let wan = [];
          wans.map(it => {
            if (it.standByRelation === info.standByRelation) {
              wan.push({
                value: it.name,
                label: it.alias,
                wan: it,
                leaf: level >= 3
              });
            }
          });
          resolve(wan);
        }
      }
    };
    this.endOptions = {
      lazy: true,
      lazyLoad: (node, resolve) => {
        const { level } = node;
        // 初始一级参数
        if (level === 0) {
          if (this.form.start.length === 4) {
            let nodes = [];
            tenants.map(item => {
              // if (item.value === this.form.start[0]) {
              //   nodes.push({
              //     value: item.value,
              //     label: item.label,
              //     leaf: level >= 3
              //   });
              // }
              nodes.push({
                value: item.value,
                label: item.label,
                leaf: level >= 3
              });
            });
            // if (this.form.start[0] !== 100000) {
            //   nodes.push({
            //     label: 'Default',
            //     leaf: false,
            //     value: 100000
            //   });
            // }
            resolve(nodes);
          }
        }
        // 二级
        if (level === 1) {
          this.$http.get({
            url: '/api/sdwan/site/getSiteListByDgId/' + node.data.value
          }).then(res => {
            let { status, resultBody } = res;
            if (status === '0') {
              let sites = [];
              resultBody.map(item => {
                if (item.id !== this.form.start[1]) {
                  sites.push({
                    value: item.id,
                    label: item.sitename,
                    info: item,
                    leaf: level >= 3
                  });
                }
              });
              resolve(sites);
            }
          });
        }
        // 三级
        if (level === 2) {
          let neArry = node.data.info.nes;
          // 判断是否存在网元
          if (neArry.length === 0) {
            let nes = [];
            resolve(nes);
          } else {
            let nes = neArry.map((item) => {
              return {
                value: item.ne.id,
                label: item.ne.userlabel,
                info: item,
                wans: node.data.info.wans,
                leaf: level >= 3
              };
            });
            resolve(nes);
          }
        }
        // 四级
        if (level === 3) {
          let wans = node.data.wans;
          let info = node.data.info;
          let wan = [];
          wans.map(it => {
            if (it.standByRelation === info.standByRelation) {
              wan.push({
                value: it.name,
                label: it.alias,
                wan: it,
                leaf: level >= 3
              });
            }
          });
          resolve(wan);
        }
      }
    };
  },
  // 过滤
  filters: {},
  data () {
    return {
      site: {},
      startOptions: {},
      endOptions: {},
      form: {
        userlabel: null,
        type: null,
        ipVersion: null,
        // deployDomain: null,
        start: [],
        end: [],
        enableSqa: false,
        startNeIpsecIp: null,
        startMask: 30,
        startAs: null,
        startWanIp: null,
        endNeIpsecIp: null,
        endMask: 30,
        endAs: null,
        endWanIp: null,
        // 丢包
        lossRatio: 70,
        // 时延
        delayThreshold: 100,
        // 抖动
        jitter: 70
      },
      rules: {
        userlabel: [{
          required: true,
          message: '请填写名称',
          trigger: 'blur'
        }],
        type: [{
          required: true,
          message: '请选择隧道类型',
          trigger: 'change'
        }],
        ipVersion: [{
          required: true,
          message: '请选择IP类型',
          trigger: 'change'
        }],
        // deployDomain: [{
        //   required: true,
        //   message: '请选择Domain',
        //   trigger: 'change'
        // }],
        start: [{
          required: true,
          message: '请选择源端',
          trigger: 'change'
        }],
        startAs: [{
          required: true,
          message: '请填写AS',
          trigger: 'blur'
        }, {
          type: 'number',
          min: 1,
          max: 4294967295,
          message: 'AS范围：1-4294967295',
          trigger: 'blur'
        }],
        end: [{
          required: true,
          message: '请选择目的端',
          trigger: 'change'
        }],
        endAs: [{
          required: true,
          message: '请填写AS',
          trigger: 'blur'
        }, {
          type: 'number',
          min: 1,
          max: 4294967295,
          message: 'AS范围：1-4294967295',
          trigger: 'blur'
        }],
        lossRatio: [{
          required: true,
          message: '不能为空',
          trigger: 'change'
        }],
        delayThreshold: [{
          required: true,
          message: '不能为空',
          trigger: 'change'
        }],
        jitter: [{
          required: true,
          message: '不能为空',
          trigger: 'change'
        }]
      }
    };
  },
  methods: {
    handleChange (val) {
      let _this = this;
      if (val.length === 0) {
        _this.form.end = [];
      } else {
        _this.form.end = [];
      }
    },
    // 返回
    cancel () {
      let _this = this;
      _this.$emit('handleChange', 0);
    },
    submitForm (formName) {
      let _this = this;
      _this.$refs[formName].validate(async (valid) => {
        if (valid) {
          // let tenants = _this.tenants;
          // let tenant = tenants.find(it => {
          //   return _this.form.start[0] === it.value;
          // });
          let current = _this.$store.state.user.user.info;
          let tenantId = current.dgId;
          if (_this.form.start[0] !== 100000) {
            tenantId = _this.form.start[0];
          }
          if (_this.form.end[0] !== 100000) {
            tenantId = _this.form.end[0];
          }
          // 隧道参数
          let params = {
            // 租户ID - 源端
            dgId: tenantId,
            // 隧道名称
            userlabel: _this.form.userlabel,
            // 隧道类型
            type: _this.form.type,
            // IP类型
            ipVersion: _this.form.ipVersion,
            // Domain
            // deployDomain: _this.form.deployDomain,
            // 源站点
            startSite: _this.form.start[1],
            // 源设备
            startNe: _this.form.start[2],
            // 源端口
            startWan: _this.form.start[3],
            // 源接口IP
            startIpsecTunnelIp: _this.form.startNeIpsecIp ? _this.form.startNeIpsecIp + '/' + _this.form.startMask : null,
            // 源AS
            startBgp: {
              jsonKeyPointBgpLocalAs: _this.form.startAs
            },
            // 源端wan口
            startWanIp: _this.form.startWanIp,
            // 目的站点
            endSite: _this.form.end[1],
            // 目的设备
            endNe: _this.form.end[2],
            // 目的端口
            endWan: _this.form.end[3],
            // 目的接口IP
            endIpsecTunnelIp: _this.form.endNeIpsecIp ? _this.form.endNeIpsecIp + '/' + _this.form.endMask : null,
            // 目的As
            endBgp: {
              jsonKeyPointBgpLocalAs: _this.form.endAs
            },
            // 目的wan口IP
            endWanIp: _this.form.endWanIp,
            // 开启监控
            enableSqa: _this.form.enableSqa,
            // 丢包
            lossRatio: _this.form.lossRatio,
            // 时延
            delayThreshold: _this.form.delayThreshold,
            // 抖动
            jitter: _this.form.jitter
          };
          _this.portStatus(_this.form.startNeIpsecIp, _this.form.endNeIpsecIp, params);
        } else {
          this.$message.error('请检查必填项！');
          return false;
        }
      });
    },
    resetForm (formName) {
      this.$refs[formName].resetFields();
      this.form = {
        userlabel: null,
        type: null,
        ipVersion: null,
        // deployDomain: null,
        start: [],
        end: [],
        enableSqa: false,
        startNeIpsecIp: null,
        startMask: 30,
        startAs: null,
        startWanIp: null,
        endNeIpsecIp: null,
        endMask: 30,
        endAs: null,
        endWanIp: null,
        // 丢包
        lossRatio: 70,
        // 时延
        delayThreshold: 100,
        // 抖动
        jitter: 70
      };
    },
    // 过滤端口状态
    // eslint-disable-next-line complexity
    portStatus (start, end, data) {
      let _this = this;
      let params = {
        commandCode: 'statics.ports',
        paras: {
          isWAN: true,
          status: 1
        }
      };
      let errs = [];
      let ipv4 = /^(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$/;
      let ipv6 = /^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){2}:([\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$/;
      if (start === '' || start === null || end === '' || end === null || _this.form.startMask === '' || _this.form.startMask === null || _this.form.endMask === '' || _this.form.endMask === null) {
        errs.push('接口地址/掩码不能为空！');
      }
      if (data.ipVersion === 'V4') {
        if (start && end) {
          if (start === end) {
            errs.push('接口地址不能相同！');
          }
          if (start.replace(ipv4) !== 'undefined' || end.replace(ipv4) !== 'undefined') {
            errs.push('接口IP格式不正确！');
          }
          if (_this.form.startMask < 0 || _this.form.startMask > 30) {
            errs.push('掩码范围：0-30');
          }
          if (_this.form.endMask < 0 || _this.form.endMask > 30) {
            errs.push('掩码范围：0-30');
          }
        }
      } else {
        if (start === end) {
          errs.push('接口地址不能相同！');
        }
        if (start.replace(ipv6) !== 'undefined' || end.replace(ipv6) !== 'undefined') {
          errs.push('接口IP格式不正确！');
        }
        if (_this.form.startMask < 0 || _this.form.startMask > 128) {
          errs.push('掩码范围：0-128');
        }
        if (_this.form.endMask < 0 || _this.form.endMask > 128) {
          errs.push('掩码范围：0-128');
        }
      }
      Promise.all([
        _this.$http.post({
          url: '/api/resource/nemng/command/' + data.startNe,
          data: params
        }),
        _this.$http.post({
          url: '/api/resource/nemng/command/' + data.endNe,
          data: params
        })
      ]).then(res => {
        for (let i = 0; i < res[0].length; i++) {
          if (res[0][i].name === data.startWan) {
            if (res[0][i].status) {
              errs.push('源端端口状态异常');
            }
          }
        }
        for (let j = 0; j < res[1].length; j++) {
          if (res[1][j].name === data.endWan) {
            if (res[1][j].status) {
              errs.push('目的端端口状态异常');
            }
          }
        }
      });
      if (errs.length === 0) {
        // 创建隧道请求
        _this.$http.post({
          url: '/api/sdwan/wan-pipeline/v1/create',
          data: data,
          loading: true
        }).then(res => {
          let { status } = res;
          if (status === '0') {
            _this.$message.success('创建成功！');
            _this.resetForm('tunnelForm');
            _this.cancel();
            _this.$parent.refresh();
          }
        });
      } else {
        if (errs[0] === '源端端口状态异常' || errs[0] === '目的端端口状态异常') {
          this.$confirm(errs[0] + ', 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            // 创建隧道请求
            _this.$http.post({
              url: '/api/sdwan/wan-pipeline/v1/create',
              data: data,
              loading: true
            }).then(res => {
              let { status } = res;
              if (status === '0') {
                _this.$message.success('创建成功！');
                _this.resetForm('tunnelForm');
                _this.cancel();
                _this.$parent.refresh();
              }
            });
          }).catch(() => {
            _this.$message({
              type: 'info',
              message: '已取消创建'
            });
          });
        } else {
          _this.$message.error(errs[0]);
        }
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.tunnel-content {
  .header {
    background: #fff;
    padding: 30px 40px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;

    .left-wrap {
      .avatar {
        width: 110px;
        height: 110px;
        object-fit: cover;
        border-radius: 50%;
      }

      h2 {
        font-size: 30px;
        margin-top: 20px;
        font-weight: 500;
      }

      p {
        color: #9ca3ae;
        font-size: 14px;
        margin-top: 20px;
        display: none;
      }

      .task {
        margin-top: 30px;
        display: flex;
        align-items: center;

        span {
          color: #9ca3ae;
          font-size: 14px;
          margin-right: 30px;
          margin-left: 8px;
        }
      }
    }

    .right-wrap {
      display: flex;
      align-items: center;

      img {
        width: 230px;
      }
    }
  }

  .info {
    background: #fff;

    .title {
      font-size: 22px;
      font-weight: 500;
      padding: 15px 40px;
      border-bottom: 1px solid #eee;
    }

    .form {
      padding: 30px 40px;
      box-sizing: border-box;

      .ip-mask {
        width: 100%;
        ::v-deep .el-input {
          float: left;
        }
        ::v-deep .el-input:first-child {
          width: 75%;
        }
        label {
          display: block;
          width: 3%;
          float: left;
          text-align: center;
        }
        ::v-deep .el-input:last-child {
          width: 22%;
          &::after {
            content: "";
            overflow: hidden;
            clear: both;
          }
        }
      }
    }
  }
}

@media only screen and (max-width: $device-ipad) {
  .tunnel-content {
    .header {
      padding: 20px 20px;

      .left-wrap {
        .avatar {
          width: 90px;
          height: 90px;
        }

        h2 {
          font-size: 20px;
          margin-top: 20px;
        }

        .task {
          margin-top: 15px;

          .icon {
            width: 2.8em;
            height: 2.8em;
            vertical-align: -0.15em;
          }

          span {
            font-size: 15px;
          }
        }
      }

      .right-wrap {
        display: flex;
        align-items: center;

        img {
          display: none;
        }
      }
    }

    .info {
      .title {
        font-size: 18px;
        padding: 15px 20px;
      }

      .form {
        padding: 30px 20px;
      }
    }
  }
}
</style>